91. Decode Ways — Medium
A message containing letters from A-Z
can be encoded into numbers using the following mapping:
To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, "11106"
can be mapped into:
"AAJF"
with the grouping(1 1 10 6)
"KJF"
with the grouping(11 10 6)
Note that the grouping (1 11 06)
is invalid because "06"
cannot be mapped into 'F'
since "6"
is different from "06"
.
Given a string s
containing only digits, return the number of ways to decode it.
The answer is guaranteed to fit in a 32-bit integer.
Example 1:
Example 2:
Example 3:
Example 4:
Constraints:
1 <= s.length <= 100
s
contains only digits and may contain leading zero(s).
#
心得
- 大晚上做题脑子非常不清醒,十分低效,不如直接睡觉
- 动规思路没有固定下来,没有形成第一时间思考状态转移方程的习惯
- 多动手debug确定如何处理所有边界情况 —— 有时可以对原始数据直接进行处理,比如整体后移或者copy到新数组上
- 三叶大佬yyds。“算法只能不断地刷题,总结,没有捷径的。”
- 类似的题目(需要格外注意边界情况)要列清楚所有边界情况,分点处理;分析要做到下面👇这种程度1:
#
Review 1:
- Decode
s[i]
:
- If 1 <=
s[i]
<= 9:dp[i] += dp[i - 1]
- Decode
s[i-1]s[i]
:
- If 10 <=
s[i-1]s[i]
< 27:dp[i] = dp[i - 2]
- If
s[i] == 0
- If
s[i - 1] == 1 or 2
,dp[i] += dp[i - 2]
- If
i == 1
,dp[i] = 1
;
#
思路边界情况:⚠️把数组长度设为n+1
,才能从 dp[i - 2]
得到记录
遍历范围是$[1, n]$
一些恼人的边界值:
1201
12
10
对于字符串 s
的任意位置 i
而言,存在三种情况:
- 只能由位置
i
的单独作为一个item
,设为a
,转移的前提是a
的数值范围为 $[1,9]$,转移逻辑为dp[i] = dp[i - 1]
。 - 只能由位置
i
的与前一位置(i - 1
)共同作为一个item
,设为b
,转移的前提是b
的数值范围为 $[10,26]$,转移逻辑为dp[i] = dp[i] + dp[i - 2]
。 - 位置
i
既能作为独立item
也能与上一位置形成item
,转移逻辑为dp[i] = dp[i - 1] + dp[i - 2]
。
dp[i] = dp[i - 1]
和dp[i] += dp[i - 1]
相同,因为dp
初始值为$0$.
其他细节:由于题目存在前导零,而前导零属于无效 item
。可以进行特判,但个人习惯往字符串头部追加空格作为哨兵,追加空格既可以避免讨论前导零,也能使下标从 1 开始,简化 dp[i - 1]
等负数下标的判断。2
所以转移方程如下:
#
最终代码运行时间:0 ms, 100.00% 运行内存:6.3 MB, 29.25%